package org.yecq.tradedata.service;

import com.jhhc.baseframework.data.record.SqlOperator;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yecq.tradedata.algorithm.BollValue;
import org.yecq.tradedata.algorithm.BollingerBandsFutures;
import org.yecq.tradedata.save.BollSaver;

/**
 * 布林线的业务
 *
 * @author yecq
 */
@Service
public class BollService {

    private static final Logger log = Logger.getLogger(BollService.class);

    @Autowired
    private BollSaver saver;

    @Autowired
    private BollingerBandsFutures boll;

    @Autowired
    private SqlOperator sql;

    // 重新计算并保存某一天的布林值
    private void reComputeDate(String code, String date) {
        code = code.toUpperCase();
        this.boll.setCode(code);
        this.boll.setDate(date);
        BollValue value = this.boll.compute();
        // value有可能是空的，空的就表示没有boll值
        if (value != null) {
            log.info("====> 生成或者修改" + code + "的" + date + "的boll值 ...");
            this.saver.saveOrUpdateByCodeDate(code, date, value);
        }
    }

    // 重新计算并保存某一天开始之后的布林值
    void reComputeDateAndAfter(String code, String start_date) {
        code = code.toUpperCase();
        // 取得所有的日期，按从小到大排列
        List<String> date_list = getDateListOfCode0(code, start_date);
        for (String date : date_list) {
            reComputeDate(code, date);
        }
    }

    // 重新计算并保存某一个品种的所有布林值
    private void reComputeDataAll(String code) {
        code = code.toUpperCase();
        List<String> date_list = getDateListOfCode0(code);
        for (String date : date_list) {
            reComputeDate(code, date);
        }
    }

    //重新计算所有期货品种的布林值
    public void reComputeDataFuturesAll() {
        List<String> code_list = getFuturesCode0List();
        for (String code : code_list) {
            reComputeDataFutures(code);
        }
    }
    
    // 重新计算所有品种从某天开始的布林值
    public void reComputeDataFuturesAllAfter(String date){
         List<String> code_list = getFuturesCode0List();
        for (String code : code_list) {
            reComputeDataFuturesAfter(code,date);
        }
    }

    // 重新计算某个品种的布林值
    public void reComputeDataFutures(String code) {
        code = code.toUpperCase();
        log.info("====> 生成或者修改" + code + "的boll值 ...");
        reComputeDataAll(code);
    }

    // 重新计算某个品种的从某天开始的布林值
    public void reComputeDataFuturesAfter(String code, String date) {
        code = code.toUpperCase();
        log.info("====> 生成或者修改" + code + "的从" + date + "开始的boll值 ...");
        reComputeDateAndAfter(code, date);
    }
    
    // 获取某品种从某一天开始的所有日期 
    private List<String> getDateListOfCode0(String code, String start_date) {
        List<Map<String, Object>> list = this.sql.query("select date from futures_day_kline where  "
                + "futures_id = (select id from futures where code=?) and date >= ? order by date", code, start_date);
        List<String> ret = new ArrayList(list.size());
        for (Map<String, Object> map : list) {
            ret.add(map.get("date") + "");
        }

        return ret;
    }

    // 获取某一个品种的所有日期 
    private List<String> getDateListOfCode0(String code) {
        List<Map<String, Object>> list = this.sql.query("select date from futures_day_kline where  "
                + "futures_id = (select id from futures where code=?) order by date", code);
        List<String> ret = new ArrayList(list.size());
        for (Map<String, Object> map : list) {
            ret.add(map.get("date") + "");
        }

        return ret;
    }

    // 获取所有品种
    private List<String> getFuturesCode0List() {
        List<Map<String, Object>> list = this.sql.query("select * from futures");
        List<String> ret = new ArrayList(list.size());
        for (Map<String, Object> item : list) {
            ret.add(item.get("code") + "");
        }
        return ret;
    }
}
